import React from 'react';
import {View, FlatList, Text, StyleSheet} from 'react-native';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as orderActionCreator from '../../actions/order-actions';
import {connectActionSheet} from '@expo/react-native-action-sheet';
import ThemeStyles from '../../styles';
import {formatDate, getRealSize, Touchable} from '../../utils';
import Search from '../../components/search';
import IconFont from '../../resource/iconfont';
import {OrderState, OrderStateName} from '../../reducers/order-list';
import {LoadingStatus} from '../../reducers/app-state';
import Drawer from 'react-native-drawer';
import {I18n} from '../../reducers/intl';
import Separator from '../../components/separator';
import OrderItem from '../../components/items/order';
import ConfirmDialog, {DialogMode} from '../../components/confirm-dialog';
import {BottomSheetModal, BottomSheetModalProvider} from '@gorhom/bottom-sheet';
import {CalendarList} from 'react-native-calendars';
import _ from 'lodash';
import * as messageActionCreator from '../../actions/message-actions';
import SheetHead from '../../components/items/sheet-head';
import Toast from '../../components/toast';
import FilterPanel from './filter-panel';
import {UserType} from '../../reducers/user';
import moment from '../../commons/moment';

class OrderListScreen extends React.Component {
  static navigationOptions = {
    header: null,
  };

  state = {
    drawer: false,
    order: {
      field: '',
      visible: false,
    },
  };

  onChangeParam = (field, value) => {
    const {orderActions} = this.props;
    orderActions.updateParams({[field]: value});
  };

  onChangeState = () => {
    const {orderActions, list} = this.props;
    const options = Object.values(OrderState).map(o => ({
      label: I18n.t(OrderStateName[o]),
      value: o,
    }));
    options.unshift({label: I18n.t('button.default'), value: ''});
    options.push({label: I18n.t('button.close')});
    this.props.showActionSheetWithOptions(
      {
        options: options.map(option => option.label),
        cancelButtonIndex: options.length,
        destructiveButtonIndex: options.length,
        textStyle: {flex: 1},
      },
      buttonIndex => {
        if (buttonIndex > options.length - 2) {
          return;
        }
        const ordering = options[buttonIndex].value;
        orderActions.updateParams({status: ordering});
        orderActions.loadOrders({...list, status: ordering}, 1);
      },
    );
  };

  toOrder = item => {
    const {navigation, orderActions, messageActions} = this.props;
    navigation.navigate('OrderDetail', {item});
    orderActions.loadOrder(item.id);
    messageActions.loadMessages();
  };

  onConfirmOrder = (field, item) => {
    const {navigation} = this.props;
    if (field === 'comment') {
      return navigation.navigate('OrderComment', {orderId: item.id});
    }
    if (field === 'confirm') {
      this.BottomSheet.present();
      const busyDates = _.get(item, 'seller.busy_dates', []);
      const dates = {};
      busyDates.forEach(o => {
        dates[o.date] = {disabled: true, disableTouchEvent: true};
      });
      this.setState({
        order: {
          field,
          visible: false,
          id: item.id,
          dates,
        },
      });
      return;
    }
    this.setState({
      order: {
        field,
        visible: true,
        id: item.id,
      },
    });
  };

  onChangeOrder = async () => {
    const {orderActions, list} = this.props;
    const {
      order: {field, id},
    } = this.state;
    await orderActions[field](id);
    orderActions.loadOrders(list, 1);
  };

  render() {
    const {list, orderActions, appState, categories, user, minDate, maxDate} = this.props;
    const orders = Object.values(list.items || []);
    const sections = {};
    if ([UserType.clinic, UserType.dentist].includes(user.type)) {
      sections.technician = list.technicianOptions;
      sections.provider = list.factoryOptions;
    } else {
      sections.dentist = list.dentistOptions;
      sections.clinic = list.clinicOptions;
    }
    const values = [];
    if (list.dentist) {
      values.push(list.dentist);
    }
    if (list.clinic) {
      values.push(list.clinic);
    }
    if (list.technician) {
      values.push(list.technician);
    }
    if (list.provider) {
      values.push(list.provider);
    }
    return (
      <Drawer
        ref={ref => (this._drawer = ref)}
        content={
          <FilterPanel
            sections={sections}
            values={values}
            type={list.type}
            onSelected={this.onChangeParam}
            onReset={() =>
              orderActions.updateParams({
                dentist: null,
                clinic: null,
                technician: null,
                provider: null,
                type: null,
              })
            }
            onApply={() => {
              this.setState({drawer: false});
              orderActions.loadOrders(list, 1);
            }}
          />
        }
        onClose={() => this.setState({drawer: false})}
        open={this.state.drawer}
        type="displace"
        tapToClose
        openDrawerOffset={0.2}
        panCloseMask={0.2}
        side="right">
        <BottomSheetModalProvider>
          <View style={Styles.container}>
            <View style={Styles.search}>
              <Search
                value={list.keyword || ''}
                placeholder={I18n.t('form.placeholder.orderSearch')}
                onChange={value => this.onChangeParam('keyword', value)}
                onSearch={() => orderActions.loadOrders(list, 1)}
              />
            </View>
            <View style={Styles.title}>
              <Touchable onPress={this.onChangeState}>
                <View>
                  <Text
                    style={[
                      ThemeStyles.Front.title.smallReg,
                      ThemeStyles.Color.text.tintGray,
                    ]}>
                    {list.status
                      ? I18n.t(OrderStateName[list.status])
                      : I18n.t('form.label.order.state')}
                  </Text>
                </View>
              </Touchable>
              <View style={Styles.filterAction}>
                <Touchable
                  onPress={() => {
                    this.setState({drawer: true});
                  }}>
                  <View
                    style={[
                      ThemeStyles.Layout.flex.row,
                      ThemeStyles.Layout.flex.horizontalCenter,
                      {paddingHorizontal: 4},
                    ]}>
                    <Text
                      style={[
                        ThemeStyles.Front.title.smallReg,
                        ThemeStyles.Color.text.tintGray,
                      ]}>
                      {I18n.t('form.label.filter')}
                    </Text>
                    <IconFont
                      name="molarshaixuan"
                      color="#979797"
                      size={getRealSize(18)}
                    />
                  </View>
                </Touchable>
              </View>
            </View>
            <View style={[ThemeStyles.divider.horizontal]} />
            <FlatList
              data={_.sortBy(orders, o => -o.id)}
              onRefresh={() => {
                orderActions.loadOrders(list, 1);
              }}
              refreshing={appState.loading === LoadingStatus.PENDING}
              onEndReached={() =>
                orderActions.loadOrders(list, list.current + 1)
              }
              onEndReachedThreshold={0.1}
              ItemSeparatorComponent={() => <Separator />}
              keyExtractor={item => item.order_no}
              renderItem={({item}) => (
                <OrderItem
                  order={item}
                  categories={categories}
                  userType={user.type}
                  userId={user.id}
                  onConfirmChange={field => this.onConfirmOrder(field, item)}
                  onOrder={() => this.toOrder(item)}
                />
              )}
            />
          </View>
          <ConfirmDialog
            okLabel={I18n.t(`order.action.${this.state.order.field}`)}
            visible={this.state.order.visible}
            title={I18n.t(`order.action.${this.state.order.field}`)}
            content={I18n.t(`order.action.${this.state.order.field}`)}
            cancelLabel={I18n.t('button.close')}
            onConfirm={this.onChangeOrder}
            mode={DialogMode.confirm}
            onClose={() => this.setState({order: {visible: false}})}
          />
          <BottomSheetModal
            ref={ref => {
              this.BottomSheet = ref;
            }}
            style={Styles.sheetContainer}
            index={0}
            handleComponent={() => (
              <SheetHead onClose={() => this.BottomSheet.close()} />
            )}
            snapPoints={[320]}>
            <CalendarList
              markedDates={this.state.order.dates}
              minDate={minDate}
              maxDate={maxDate}
              pastScrollRange={0}
              futureScrollRange={3}
              onDayPress={async day => {
                try {
                  await orderActions.confirm(
                    this.state.order.id,
                    day.dateString,
                  );
                } catch (e) {
                  Toast.show(e.message);
                }
                orderActions.loadOrders(list, 1);
                this.BottomSheet.dismiss();
              }}
            />
          </BottomSheetModal>
        </BottomSheetModalProvider>
      </Drawer>
    );
  }
}

const mapStateToProps = state => ({
  appState: state.appState,
  user: state.user,
  list: state.orderList,
  categories: state.constant.category,
  selectionOptions: state.constant.selections,
  minDate: formatDate(),
  maxDate: formatDate(moment().add(3, 'months').toDate())
});

const mapDispatchToProps = dispatch => ({
  orderActions: bindActionCreators(orderActionCreator, dispatch),
  messageActions: bindActionCreators(messageActionCreator, dispatch),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(connectActionSheet(OrderListScreen));

const Styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  title: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginHorizontal: getRealSize(16),
    marginVertical: getRealSize(6),
  },
  filterAction: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  search: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginHorizontal: getRealSize(16),
    marginTop: getRealSize(16),
  },
  sheetContainer: {
    borderTopColor: ThemeStyles.Color.line.color,
    borderTopWidth: StyleSheet.hairlineWidth,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 12,
    },
    shadowOpacity: 0.58,
    shadowRadius: 16.0,

    elevation: 24,
  },
});
